package github.ziwukun.jsonql.lang;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import cn.hutool.core.util.StrUtil;

/**
 * 限制语句
 * @author Hugo.Yu
 */
public class LimitImpl implements Limit{
	private static final long serialVersionUID = 2624910029778009461L;
	String model;
	Integer size;
	Integer offset;
	Integer page;
	List<Limit> childs = new LinkedList<>();
	
	LimitImpl(String model, Integer size, Integer offset, Integer page, List<Limit> childs) {
		super();
		this.model = model;
		this.size = size;
		this.offset = offset;
		this.page = page;
		this.childs.addAll(childs);
		
		asserts();
	}

	@Override
	public String model() {
		return model;
	}

	@Override
	public Integer size() {
		return size;
	}

	@Override
	public Integer offset() {
		return offset;
	}

	@Override
	public Integer page() {
		return page;
	}

	@Override
	public List<Limit> childs() {
		return new ArrayList<>(childs);
	}
	
	@Override
	public boolean isChildsEmpty() {
		return childs.isEmpty();
	}
	
	private void asserts() {
		if(StrUtil.isBlank(model)) {
			throw new JSONQLBuildException("limit语句model参数不能为空字符串");
		}
		if(size == null || size  < 0) {
			throw new JSONQLBuildException("limit语句size参数不能为空或小于0");
		}
		if(offset == null && page == null) {
			throw new JSONQLBuildException("limit语句offset参数,page参数不能同时为空");
		}
		if(offset != null && offset < 0) {
			throw new JSONQLBuildException("limit语句offset参数不能小于0");
		}
		if(page != null && page < 0) {
			throw new JSONQLBuildException("limit语句page参数不能小于0");
		}
		
		if(childs == null) {
			childs = new ArrayList<>();
		}
	}

	@Override
	public String toJSONQL() {
		return LimitJson.writeJson(this);
	}

	@Override
	public Limit repModel(String model) {
		return new LimitImpl(model, size, offset, page, childs);
	}

	@Override
	public Limit repSize(Integer size) {
		return new LimitImpl(model, size, offset, page, childs);
	}

	@Override
	public Limit repOffset(Integer offset) {
		return new LimitImpl(model, size, offset, page, childs);
	}

	@Override
	public Limit repPage(Integer page) {
		return new LimitImpl(model, size, offset, page, childs);
	}

	@Override
	public Limit repChilds(List<Limit> limit) {
		return new LimitImpl(model, size, offset, page, limit);
	}
}
